package com.tianhua.javs.client.bean;

import com.tianhua.javs.client.model.*;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;

/**
 * Description: 领域模型bean
 * date: 2022/2/9
 *
 * @author shenshuai
 * @version 1.0.0
 * @since JDK 1.8
 */
public class DomainModelBean {
    /**
     * 当前系统名称，组件别名
     */
    private String currentCompName;

    /**
     * key 组件名
     */
    private Map<String, Map<String, ClassModel>> classBeanMap = new HashMap<>();
    /**
     * key 组件名
     */
    private Map<String, Map<String, EnumModel>> enumBeanMap = new HashMap<>();
    /**
     * key 组件名
     */
    private Map<String, Map<String, InterfaceModel>> interfaceBeanMap = new HashMap<>();
    /**
     * key 组件名
     * child key 类名
     */
    private Map<String, Map<String, String>> packageMap = new HashMap<>();


    public Map<String, Map<String, ClassModel>> getClassBeanMap() {
        return classBeanMap;
    }

    public Map<String, Map<String, EnumModel>> getEnumBeanMap() {
        return enumBeanMap;
    }

    public Map<String, Map<String, InterfaceModel>> getInterfaceBeanMap() {
        return interfaceBeanMap;
    }

    public Map<String, Map<String, String>> getPackageBeanMap() {
        return packageMap;
    }

    public String getCurrentCompName() {
        return currentCompName;
    }

    public void setCurrentCompName(String currentCompName) {
        this.currentCompName = currentCompName;
    }

    public void addClassBean(ClassModel classBean) {
        Map<String, ClassModel> classBeanMap = this.classBeanMap.get(classBean.getCompName());
        if (classBeanMap == null) {
            classBeanMap = new HashMap<>();
        }
        classBeanMap.put(classBean.getClassName(), classBean);
        this.classBeanMap.put(classBean.getCompName(), classBeanMap);
    }

    public void addInterfaceBean(InterfaceModel interfaceBean) {
        Map<String, InterfaceModel> interfaceBeanMap = this.interfaceBeanMap.get(interfaceBean.getCompName());
        if (interfaceBeanMap == null) {
            interfaceBeanMap = new HashMap<>();
        }
        interfaceBeanMap.put(interfaceBean.getClassName(), interfaceBean);
        this.interfaceBeanMap.put(interfaceBean.getCompName(), interfaceBeanMap);
    }

    public void addEnumBean(EnumModel enumBean) {
        Map<String, EnumModel> enumBeanMap = this.enumBeanMap.get(enumBean.getCompName());
        if (enumBeanMap == null) {
            enumBeanMap = new HashMap<>();
        }
        enumBeanMap.put(enumBean.getClassName(), enumBean);

        this.enumBeanMap.put(enumBean.getCompName(), enumBeanMap);
    }


    /**
     * 根据组件名和类名找到类模型
     * @param compName
     * @param className
     * @return
     */
    public AbstractClassModel searchClass(String compName, String  className) {
        if(StringUtils.isEmpty(className)){
            return null;
        }
        if(StringUtils.isEmpty(compName)){
            Map<String,ClassModel> classModelMap = this.getClassBeanMap().get(this.currentCompName);
            if(classModelMap != null && classModelMap.containsKey(className)){
                return  classModelMap.get(className);
            }
            Map<String,EnumModel> enumModelMap = this.getEnumBeanMap().get(this.currentCompName);
            if(enumModelMap != null && enumModelMap.containsKey(className)){
                return  enumModelMap.get(className);
            }
        }

        return null;
    }


    /**
     * 根据类名,方法名,方法参数 数量找到指定方法
     * @param className
     * @param methodName
     * @param paramCount
     * @return
     */
    public MethodModel searchMethod(String  className,String methodName,int paramCount) {
        String newClassName = className.trim().substring(0,1).toUpperCase() + className.trim().substring(1);
        List<MethodModel> methodModelList = getMethodModeList(newClassName);
        if(CollectionUtils.isEmpty(methodModelList)){
            return null;
        }
        for(MethodModel methodModel : methodModelList){
            int count = 0;
            if(CollectionUtils.isNotEmpty(methodModel.getParamModelList())){
                count = methodModel.getParamModelList().size();
            }
            if(methodModel.getMethdSimpleName().equals(methodName) && count == paramCount){
                return methodModel;
            }
        }
        return null;
    }

    private List<MethodModel> getMethodModeList(String className){
        if(this.getClassBeanMap() == null || this.getClassBeanMap().isEmpty()){
            return null;
        }
        Map<String,ClassModel> classModelMap = this.getClassBeanMap().get(this.currentCompName);
        if(classModelMap == null || classModelMap.isEmpty()){
            return null;
        }
        ClassModel classModel = classModelMap.get(className);
        if(classModel != null){
            List<MethodModel> list = new ArrayList<>();
            list.addAll(classModel.getSuperMethodBeanList());
            list.addAll(classModel.getMethodBeanList());
            return list;
        }
        Map<String,InterfaceModel> interfaceModelMap = this.getInterfaceBeanMap().get(this.currentCompName);
        InterfaceModel interfaceModel = interfaceModelMap.get(className);
        if(interfaceModel != null){
            List<MethodModel> list = new ArrayList<>();
            list.addAll(interfaceModel.getSuperMethodBeanList());
            list.addAll(interfaceModel.getMethodBeanList());
            return list;
        }
        return null;
    }



    /**
     * 根据类名找对应的包
     * @param className
     * @return
     */
    public String searchPackageName(String  className){
        if(StringUtils.isEmpty(className)){
            return null;
        }
        Map<String,String> packageMap = this.getPackageBeanMap().get(this.currentCompName);
        AtomicReference<String> packageName = new AtomicReference<>();
        if(packageMap != null){
            packageName.set(packageMap.get(className));
        }
        if(StringUtils.isNotEmpty(packageName.get())){
            return packageName.get();
        }
        this.getPackageBeanMap().forEach((k,v)->{
            String packageNamex = v.get(className);
            if(StringUtils.isNotEmpty(packageNamex)){
                packageName.set(packageNamex);
            }
        });
        if(StringUtils.isNotEmpty(packageName.get())){
            return packageName.get();
        }
        return null;
    }


}
